package com.study.web.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 系统功能：响应时长 AOP实现<br>
 * ResponseTimeAop.java
 * 
 * @author yaojinshan
 * @since 2018年6月14日上午10:10:56
 */
@Aspect
@Order(2)
@Component
public class ResponseTimeAop {
	
	static Logger logger = LoggerFactory.getLogger(ResponseTimeAop.class);
    static Logger slowResponseLog = LoggerFactory.getLogger("slowResponse");
	
	@Pointcut("(execution(*  com.study.web.action..*.*(..))) && !(execution(*  com.study.web.action.RequestPageController.*(..)))")
	public void declearJoinPointExpression() {
	
	}

	@Before("declearJoinPointExpression()") // 该标签声明次方法是一个前置通知：在目标方法开始之前执行
	public void beforMethod(JoinPoint joinPoint) {
		
	}

	@After("declearJoinPointExpression()")
	public void afterMethod(JoinPoint joinPoint) {
	}

	@AfterReturning(value = "declearJoinPointExpression()", returning = "result")
	public void afterReturnMethod(JoinPoint joinPoint, Object result) {
	}

	@AfterThrowing(value = "declearJoinPointExpression()", throwing = "ex")
	public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) {
	}

	@Around(value = "declearJoinPointExpression()")
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
		String execName = pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName();
		logger.info("=====method: " + execName +"--------BEGIN--------");
        //1.获取到所有的参数值的数组
        Object[] args = pjp.getArgs();
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        //2.获取到方法的所有参数名称的字符串数组
        String[] parameterNames = methodSignature.getParameterNames();
        StringBuilder sb = new StringBuilder();
        sb.append("请求方法：" + execName + "，请求参数[");
        for(int i = 0; i < parameterNames.length; i++){
            sb.append(parameterNames[i] + ":" + args[i] + ",");
        }
        sb.append("]");
        logger.info(sb.toString());
		long time = System.currentTimeMillis();
		Object result = pjp.proceed();
        time = System.currentTimeMillis() - time;
        //接口响应超过三秒加入慢响应接口访问日志
        if(time >= 3000 ){
            slowResponseLog.info(execName + "------process time:" + time + " ms");
        }
        logger.info("=====method: " + execName +"--------END--------process time:"+ time + " ms");
        return result;
	}
}
